package chapter04

/**
  * 匿名函数
  */
object Test05_Lambda {
  def main(args: Array[String]): Unit = {

    // 格式定义: val 函数名:函数参数类型列表=>函数返回值=(参数列表)={函数体}
    val fun: String => Unit = (name: String) => {
      println(name)
    }

    //定义一个函数,以函数作为参数输入，--- 单参数
    def f(function: String => Unit): Unit = {
      function("函数式编程")
    }

    fun("atguigu")

    //定义一个函数,以函数作为参数输入 -- 多参数
    val fun2: (String, Int) => String = (name: String, age: Int) => {
      s"$name:$age"
    }

    def f2(function: (String, Int) => String): Unit = {
      println(function("scale", 666))
    }

    f2(fun2)

    // 调用方式
    //方式1
    f(fun)
    // 方式2
    f((name: String) => {
      println(name)
    })
    // 方式3,只有一个参数，圆括号可以省略,函数体只有一行,花括号可以省略
    f(name => {
      println(name)
    })
    // 方式4,参数只出现一次,参数省略后且后面参数可以用_代替
    f(println(_))
    //方式5,传入的是一个函数体，不是调用语句，可以直接省略下划线
    f(println)


    // 实际示例,定义一个二元运算函数,只操作1和2两个数，但是具体运算通过参数参数传递

    def dualFunctionOneAndTwo(func: (Int, Int) => Int): Int = {
      func(1, 2)
    }

    val add = (a: Int, b: Int) => a + b
    val munus = (a: Int, b: Int) => a - b

    println(dualFunctionOneAndTwo(add))
    println(dualFunctionOneAndTwo(munus))
    println(dualFunctionOneAndTwo((a: Int, b: Int) => a + b))
    println(dualFunctionOneAndTwo((a: Int, b: Int) => a - b))

    println(dualFunctionOneAndTwo( _ + _))
    println(dualFunctionOneAndTwo(_ - _))


  }
}
